package tcp

import (
	"context"
	"fmt"
	"my-godis/interface/tcp"
	"my-godis/lib/logger"
	"net"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"
)

type Config struct {
	Address string `yaml:"address"`
	MaxConnect uint32 `yaml:"max-connect"`
	Timeout time.Duration `yaml:"timeout"`
}

func ListenAndServeWithSignal(cfg *Config, handler tcp.Handler) error{
	closeChan := make(chan struct{})
	sigCh := make(chan os.Signal)
	// 当出现这些终止信号量时，将信号发送给sigCH
	signal.Notify(sigCh,syscall.SIGHUP,syscall.SIGQUIT,syscall.SIGINT,syscall.SIGTERM)
	go func() {
		// 如果sig接受到信号量 判断 如果是退出信号量 就发给closeChan 表示需要退出了
		sig := <- sigCh
		switch sig {
		case syscall.SIGHUP,syscall.SIGQUIT,syscall.SIGINT,syscall.SIGTERM:
			closeChan <- struct{}{}
		}
	}()
	listener, err := net.Listen("tcp", cfg.Address)
	if err != nil {
		return err
	}
	logger.Info(fmt.Sprintf("bind: %s, start listening", cfg.Address))
	ListenAndServe(listener,handler,closeChan)
	return nil
}
func ListenAndServe(listener net.Listener, handler tcp.Handler, closeChan <- chan struct{}) {
	// 监听关闭通知
	go func() {
		<- closeChan
		// closeChan有通知进来才进入下面
		logger.Info("shutting down...")
		_ = listener.Close()
		_ = handler.Close()

	}()
	// 为什么要重复关？ 因为如果是异常退出 也要关闭！
	defer func() {
		_ = listener.Close()
		_ = handler.Close()
	}()
	// 创建一个ctx 传递给handler用 可以表示层次关系？
	ctx := context.Background()
	var wg sync.WaitGroup
	for {
		conn, err := listener.Accept()
		if err != nil {
			break
		}
		logger.Info("accept link")
		wg.Add(1)
		go func() {
			defer func() {
				wg.Done()
			}()
			handler.Handle(ctx,conn)
		}()
	}
	wg.Wait()
}